package com.han.verifycode.ver.point;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.han.verifycode.CodeConfig;
import com.han.verifycode.data.*;
import com.han.verifycode.data.area.CircleArea;
import com.han.verifycode.enums.VerifyCodeEnum;
import com.han.verifycode.utils.FileUtil;
import com.han.verifycode.utils.FontsUtil;
import com.han.verifycode.utils.RandomUtil;
import com.han.verifycode.utils.StrUtil;
import com.han.verifycode.ver.PointAreaMatchCode;
import com.han.verifycode.ver.conf.IdiomPointConf;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 *
 */
public class IdiomPointCode implements PointAreaMatchCode {
    private IdiomPointConf thisConf;
    private VerifyCodeEnum type = VerifyCodeEnum.IdiomPoint;

    @Override
    public RightKey generate(String code, CodeConfig conf) {
        RightKey key = new RightKey(code);
        if (conf == null) {
            thisConf = new IdiomPointConf();
        } else {
            thisConf = (IdiomPointConf) conf;
        }
        key.setConfig(thisConf);
        key.setType(type);
        key.setWidth(conf.getWidth());
        key.setHeight(conf.getHeight());

        //随机成语
        //中文
        String content = StrUtil.getRandomIdiom(thisConf.getIdiomDataSource());
        key.setDesc(content);
        key.setTips("请按顺序点击成语：" + content);
        //找到背景图
        InputStream input = FileUtil.getFile(thisConf.getBackgroundDataSource());
        ObjectMapper mapper = StrUtil.getMapper();
        ArrayData re = null;
        try {
            re = mapper.readValue(input, new TypeReference<ArrayData<String>>() {
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        List<String> s = re.getArrays();
        int index = RandomUtil.getRandom().nextInt(s.size() - 1);
        String backgroundImageUrl = s.get(index);
        //文件名
        FullPath fullPath = generateFilePath(thisConf.getBasePath(), key.getCode());
        key.setFullPath(fullPath);
        try {
            draw(key, backgroundImageUrl);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return key;
    }


    /**
     * 画图
     *
     * @param key
     * @param backgroundImageUrl
     * @throws IOException
     */
    private void draw(RightKey key, String backgroundImageUrl) throws IOException {
        int width = this.thisConf.getWidth();
        int height = this.thisConf.getHeight();
        String content = key.getDesc();
        Random random = RandomUtil.getRandom();
        Color[] colorSpaces = new Color[]{Color.WHITE, Color.CYAN,
                Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE,
                Color.PINK, Color.YELLOW};

        //背景


        BufferedImage background = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        BufferedImage buffImg = ImageIO.read(FileUtil.getFile(backgroundImageUrl));
        Graphics2D gp2d = background.createGraphics();
        //设置背景图
        gp2d.drawImage(buffImg, 0, 0, width, height, null);
        //写字
        gp2d.setColor(Color.RED);
        //计算三条线的位置
        int r = width / 10;
        int sw = width / 4;
        int fontSize = r;
        Font font = FontsUtil.getRandomFont(fontSize);
        gp2d.setFont(font);

        Map<String, Area> areaMap = new HashMap<>();
        //打乱成语

        String shuffledContent = StrUtil.shuffle(content);
        for (int i = 0; i < 4; i++) {
            //计算中心位置（随机）
            int cx = (int) (Math.floor((sw - 2 * r) * random.nextDouble())) + i * sw;
            int cy = (int) (r + Math.floor((height - 2 * r) * random.nextDouble()));
            //计算文字位置
            //这里的0.85 为适配值
            double enlargeScale = 0.85;
            int fx = cx;
            int fy = cy + (int) (r * enlargeScale);
            gp2d.setColor(colorSpaces[random.nextInt(colorSpaces.length - 1)]);
            String word = shuffledContent.substring(i, i + 1);
            areaMap.put(word, new CircleArea(new Position(cx + r, cy + r), r));
            gp2d.drawString(word, fx, fy);
        }
        //正序排列

        List<Area> areas = new ArrayList<>();
        Stream.of(content.split("")).forEach(word -> {
            Area area = areaMap.get(word);
            areas.add(area);
        });
        key.setPositions(areas);

        gp2d.dispose();
        ImageIO.write(background, "jpg", new File(key.getFullPath().getAbsolutePath()));
    }

    @Override
    public CodeConfig getConfig() {
        return thisConf;
    }


}
